#include <ArduinoJson.h>
#include <U8g2lib.h>
#include <HTTPClient.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <Wire.h>
#include <SPI.h>

#define SERVERWIFISSID "coat"
#define SERVERWIFIPWD "0123456789"
#define ADDTEMP_PIN 18
#define CUTTEMP_PIN 19
#define LED_PIN 17
#define BUZZER_PIN 16
#define OVERTIMENUM 3//和服务器通讯n次失败会触发重连机制
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0 , /* reset=*/ U8X8_PIN_NONE);

const char* host = "192.168.4.1";    // 即将连接服务器网址/IP
const int httpPort = 80;               // 即将连接服务器端口，通常是80

volatile double setTemperature = 0;
double accuracyTemperature = 0.5;
//double nowTemperature = 0;//设备实时温度
bool refreshScreen = false;
uint64_t updataTime = 0;

int hr_0 = 0 , hr_1 = -1 , o2_0 = 0  ;
float o2_1 = -1,temp_0 = -1;
int errNum = 0;

void setup(void)
{
	Serial.begin(115200);                  // 启动串口通讯
	Serial.println();

	u8g2.begin();
	u8g2.enableUTF8Print();
	u8g2.setFont(u8g2_font_wqy12_t_gb2312);
	u8g2.setFontDirection(0);
	u8g2.clearBuffer();

	WiFi.mode(WIFI_MODE_STA);
	WiFi.begin(SERVERWIFISSID , SERVERWIFIPWD);
	Serial.print("正在连接到：");
	Serial.print(SERVERWIFISSID);
	u8g2.clear();
	u8g2.setCursor(0 , 20);
	u8g2.print("正在连接服务器...");
	u8g2.sendBuffer();
	//u8g2.sendBuffer();
	int conn_try_num = 0;//尝试连接wifi的时间
	while ( WiFi.status() != WL_CONNECTED )
	{ // 尝试进行wifi连接。
		delay(1000);
		conn_try_num++;
		Serial.print(".");
		if ( conn_try_num > 10 )
		{
			Serial.println("wifi连接超时。。。");
			u8g2.setCursor(0 , 35);
			u8g2.print("服务器连接超时!");
			u8g2.sendBuffer();
			delay(60000);
			ESP.restart();
		}
	}
	u8g2.setCursor(0 , 35);
	u8g2.print("服务器连接成功!");
	u8g2.sendBuffer();
	pinMode(ADDTEMP_PIN , INPUT_PULLUP);
	pinMode(CUTTEMP_PIN , INPUT_PULLUP);
	pinMode(LED_PIN , OUTPUT);
	pinMode(BUZZER_PIN , OUTPUT);
	digitalWrite(BUZZER_PIN , HIGH);
	delay(1500);
	xTaskCreatePinnedToCore(//需要深入学习
		runData_tack                                     //创建任务
		, "runData_tack"                                 //创建任务的名称
		, 1024 * 2                                   //分配的运行空间大小
		, NULL                                       //任务句柄
		, 2                                           //任务优先级
		, NULL                                        //回调函数句柄
		, 1);

}

void runData_tack(void* pvParameters)
{
	volatile bool state[2] = {};
	while ( true )
	{
		if ( digitalRead(ADDTEMP_PIN) == LOW )
		{
			state[0] = true;
		}
		if ( digitalRead(CUTTEMP_PIN) == LOW )
		{
			state[1] = true;
		}
		if ( state[0] && digitalRead(ADDTEMP_PIN) == HIGH )
		{
			setTemperature += accuracyTemperature;
			state[0] = false;
			refreshScreen = true;
			Serial.println(setTemperature);
		}
		if ( state[1] && digitalRead(CUTTEMP_PIN) == HIGH )
		{
			setTemperature -= accuracyTemperature;
			state[1] = false;
			refreshScreen = true;
			Serial.println(setTemperature);
		}
		delay(10);
	}
}

int num = 0;
void loop(void)
{
	if ( digitalRead(CUTTEMP_PIN) == LOW )
	{
		num++;
	}
	if ( num>=30 )
	{
		digitalWrite(BUZZER_PIN , HIGH);//手动关闭蜂鸣器
	}
	if ( refreshScreen )
	{
		String displayData[4];
		displayData[0] = "设置设备温度:";
		displayData[0] += setTemperature;
		displayData[0] += "℃";
		displayData[1] = "设置实时温度:";
		displayData[1] += temp_0;
		displayData[1] += "℃";
		displayData[2] = "心率:"; //心率65 / min  血氧99 %
		displayData[2] += hr_1;
		displayData[2] += "次每分";
		displayData[3] = "血氧:";
		displayData[3] += o2_1;
		displayData[3] += "%";
		u8g2.clear();
		u8g2.setCursor(0 , 15);
		u8g2.print(displayData[0]);
		u8g2.setCursor(0 , 30);
		u8g2.print(displayData[1]);
		u8g2.setCursor(0 , 45);
		u8g2.print(displayData[2]);
		u8g2.setCursor(0 , 60);
		u8g2.print(displayData[3]);
		u8g2.sendBuffer();
		refreshScreen = false;
	}

	if ( updataTime + 5000 < millis() )
	{
		updataTime = millis();
		// 发送请求
		wifiClientRequest();
	}
	delay(100);
}

void wifiClientRequest()
{
	WiFiClient client;

	// 将需要发送的数据信息放入客户端请求
	String url = "/update?setT=" + String(setTemperature);

	// 建立字符串，用于HTTP请求
	String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" +
		"Host: " + host + "\r\n" +
		"Connection: close\r\n" +
		"\r\n";

	/*Serial.print("Connecting to ");
	Serial.print(host);*/

	if ( client.connect(host , httpPort) )
	{  //如果连接失败则串口输出信息告知用户然后返回loop
		Serial.println(" Sucess");

		client.print(httpRequest);
		//Serial.println("向服务器发送：");
		//Serial.println(httpRequest);
		//// 获取并显示服务器响应状态行 
		//String status_response = client.readStringUntil('\n');
		//Serial.print("status_response: ");
		//Serial.println(status_response);

		//// 使用find跳过HTTP响应头
		if ( !client.find("\r\n\r\n") )
		{
			Serial.println("err!");
		}

		String data = client.readString();
		Serial.println(data);

		StaticJsonDocument<192> doc;

		DeserializationError error = deserializeJson(doc , data);

		if ( error )
		{
			Serial.print("deserializeJson() failed: ");
			Serial.println(error.c_str());
			return;
		}
		hr_0 = doc["hr"][0]; // 0
		o2_0 = doc["o2"][0]; // 0

		if ( temp_0 != (int) doc["temp"][0] )
		{
			refreshScreen = true;
		}

		temp_0 = doc["temp"][0]; // 25
		//temp_1 = doc["temp"][1]; // 14
		if ( hr_0 == 1 )
		{
			Serial.println("有效心率");
			refreshScreen = true;
			hr_1 = doc["hr"][1]; // 64
			if ( 60<hr_1 && hr_1 < 110 )
			{
				digitalWrite(LED_PIN,LOW);
			} else
			{
				digitalWrite(LED_PIN , HIGH);
			}
		} else
		{
			Serial.println("无效心率");
		}

		if ( o2_0 == 1 )
		{
			Serial.println("有效血氧");
			refreshScreen = true;
			o2_1 = doc["o2"][1]; // -999
			if ( o2_1>100 )
			{
				o2_1 = 100;
			}
		} else
		{
			Serial.println("无效血氧");
		}
		Serial.print("设备温度:");
		Serial.println(temp_0);
		Serial.print("是否跌倒:");
		Serial.println((int) doc["temp"][1]);
		if ( !((int) doc["temp"][1]==1) )
		{
			digitalWrite(BUZZER_PIN , HIGH);
		} else
		{
			digitalWrite(BUZZER_PIN , LOW);
		}
	} else
	{
		Serial.println(" failed");
		errNum++;
		if ( OVERTIMENUM < errNum )
		{
			Serial.println("重新连接到服务器！");
			ESP.restart();
		}
	}

	client.stop();
}
